001    package net.sf.xdc.util;
002    
003    /*
004     *  Copyright 2005-2006 Jens Voß.
005     *
006     *  Licensed under the GNU Lesser General Public License (the "License");
007     *  you may not use this file except in compliance with the License.
008     *  You may obtain a copy of the License at
009     *
010     *       http://opensource.org/licenses/lgpl-license.php
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    
019    import java.net.URLConnection;
020    import java.net.URL;
021    import java.net.URLStreamHandler;
022    import java.net.URLStreamHandlerFactory;
023    import java.io.IOException;
024    import java.io.InputStream;
025    
026    import org.apache.log4j.Logger;
027    
028    /**
029     * This class contains all functionality required for processing URLs with the
030     * <em>classpath</em> protocol.
031     *
032     * @author Jens Voß
033     * @since 0.5
034     * @version 0.5
035     */
036    public class ClasspathURLConnection extends URLConnection {
037    
038      private static final Logger LOG = Logging.getLogger();
039    
040      private static class StreamHandler extends URLStreamHandler {
041    
042        protected URLConnection openConnection(URL u) throws IOException {
043          return new ClasspathURLConnection(u);
044        }
045      }
046    
047      /**
048       * This (inner) class is a factory class which produces a suitable
049       * <code>URLStreamHandler</code> object which is capable of dealing with the
050       * <em>classpath</em> protocol.
051       */
052      public static class StreamHandlerFactory
053              implements URLStreamHandlerFactory {
054    
055        /**
056         * This method creates a URLStreamHandler for the <em>classpath</em>
057         * protocol.
058         *
059         * @param protocol The protocol
060         * @return A new ClasspathURLStreamHandler if the protocol is "classpath";
061         * null otherwise
062         */
063        public URLStreamHandler createURLStreamHandler(String protocol) {
064          return "classpath".equals(protocol) ? new StreamHandler() : null;
065        }
066    
067      }
068    
069      private URL parent;
070      private URLConnection parentConnection;
071    
072      /**
073       * This constructor sets up a "shadow" parent URL (typically either with
074       * "file" or "jar" protocol) for accessing the content.
075       * 
076       * @param url The URL with protocol <em>classpath</em>
077       */
078      private ClasspathURLConnection(URL url) {
079        super(url);
080        ClassLoader cl = this.getClass().getClassLoader();
081        String resourceName = url.getFile();
082        if (resourceName.charAt(0) == '/') {
083          resourceName = resourceName.substring(1);
084        }
085        parent = cl.getResource(resourceName);
086        if (parent == null) {
087          LOG.warn("Resource " + url + " not found.");
088        }
089      }
090    
091      /**
092       * This method opens a the parent URL's connection.
093       * @throws IOException
094       */
095      public void connect() throws IOException {
096        parentConnection = parent.openConnection();
097      }
098    
099      /**
100       * This method retrieves the InputStream of the parent URL.
101       * @return The parent URL's InputStream
102       * @throws IOException
103       */
104      public InputStream getInputStream() throws IOException {
105        if (parentConnection == null) {
106          connect();
107        }
108        return parentConnection.getInputStream();
109      }
110    
111    }